#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/9/21 0021 19:11
# @Author  : GXl
# @File    : config.py
# @Software: win10 Tensorflow1.13.1 python3.7


import os
import platform
import sys
import yaml
import traceback
import threading


class Config:
    #单例模式使用
    _instance_lock = threading.Lock()

    ##########################默认初始化文件路径################
    name='mybookstore-app'
    ##########################默认是生产环境####################
    ENV=os.environ.get('FLASK_ENV') or 'production'
    VERSION='v1.0.0'
    ##########################数据库配置########################
    SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:5620079@localhost:3306/mybookstore?charset=utf8"
    #SQLALCHEMY的DEBUG配置
    DEBUG=True
    SQLALCHEMY_ECHO = True
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    ##########################登录及安全配置########################
    SECRET_KEY = os.environ.get('MY_SECRET_KEY') or 'MY_SECRET_KEY'
    TOKEN_EXPIRATION=600
    ##########################文件上传目录及模板路径########################
    #上传文件所在目录
    UPLOAD_FOLDER = os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.getcwd())), 'upload'))
    ALLOWED_EXTENSIONS = set(['xls','xlsx'])
    #模板文件所在的路径
    TEMPLATE_DIR=os.path.abspath(os.path.join(os.getcwd(), 'resources'))
    DOWNLOAD_DIR=os.path.abspath(os.path.join(os.getcwd(), 'download'))
    ###########################日志配置####################################
    #日志级别
    FILELOGLEVEL = 'DEBUG'
    GLOABLELOGLEVEL = 'DEBUG'
    CONSOLELOGLEVEL = 'DEBUG'
    # 日志文件所在路径
    LOGDIR = os.path.abspath(os.path.join(os.path.abspath(os.path.join(os.getcwd())), 'logs'))
    ##########################jsonify配置##################################
    # 返回json的配置
    JSON_AS_ASCII = False
    ##########################微服务清单##################################
    MICROSERVICES={}
    ##########################其他杂项配置可以写在下面##################################

    def __init__(self):
        print('**检测配置文件**')
        if Config.ENV =='development':
            print('检测到是测试环境')
            configfilename = 'config-dev.yaml'
            Config.DEBUG = True
        else:
            print('检测到是生产环境')
            configfilename='config-prod.yaml'
            Config.DEBUG = False
        Config.CONFIGFILE = os.environ.get('MYAPP_CONFIGFILE') or os.path.abspath(
            os.path.join(os.path.abspath(os.path.join(os.getcwd())), 'config', configfilename))
        if 'linux' in platform.system().lower():
            if os.path.exists('/etc/app/config/'+configfilename):
                # 重置配置文件所在路径
                Config.CONFIGFILE = '/etc/myapp/config/'+configfilename
                print('检测到运行在linux系统，使用配置文件路径{}'.format(Config.CONFIGFILE))
        try:
            print('Config.CONFIGFILE='+Config.CONFIGFILE)
            with  open(Config.CONFIGFILE, 'r', encoding="utf-8") as file:
                userconfig = yaml.load(file, Loader=yaml.FullLoader)
                print('**开始加载配置文件**')
                # 1、数据库配置
                if 'dbConfig' in userconfig:
                    dbconfig = userconfig['dbConfig']
                    Config.SQLALCHEMY_DATABASE_URI="mysql+pymysql://{username}:{password}@{host}:{port}/{dbname}?charset=utf8".format_map(dbconfig)
                #2、redis配置
                if 'redisConfig' in userconfig:
                    redisconfig = userconfig['redisConfig']
                    Config.REDIS_URL ="redis://{host}:{port}/0".format_map(redisconfig)
                #3、日志配置
                if 'logging' in userconfig:
                    levellst = ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FALTAL']
                    loggingconfig = userconfig['logging']
                    if 'gloableLogLevel' in loggingconfig:
                        if  loggingconfig['gloableLogLevel'] in levellst:
                            Config.GLOABLELOGLEVEL = loggingconfig['gloableLogLevel']
                        else:
                            raise Exception('{} 配置必须为 {} 之一'.format('gloableLogLevel', levellst))

                    if 'fileLogLevel' in loggingconfig:
                        if loggingconfig['fileLogLevel'] in levellst:
                            Config.FILELOGLEVEL = loggingconfig['fileLogLevel']
                        else:
                            raise Exception('{} 配置必须为 {} 之一'.format('gloableLogLevel', levellst))

                    if 'consoleLogLevel' in loggingconfig:
                        if loggingconfig['consoleLogLevel'] in levellst:
                            Config.CONSOLELOGLEVEL = loggingconfig['consoleLogLevel']
                        else:
                            raise Exception('{} 配置必须为 {} 之一'.format('consoleLogLevel', levellst))
                    # 日志路径配置
                    if 'logDir' in loggingconfig:
                        logdir = loggingconfig['logDir']
                        if 'linux' in platform.system().lower():
                            if isinstance(logdir, str) and logdir.startswith('/') and os.path.exists(logdir):
                                Config.LOGDIR = logdir
                #4、微服务配置
                if 'microservices' in userconfig:
                    Config.MICROSERVICES=userconfig['microservices']

        except FileNotFoundError:
            #打印异常堆栈
            traceback.print_exc()
            print("配置文件未找到，使用系统默认配置！")
        except Exception as e:
            traceback.print_exc()
            print("错误:{},{}".format(e, " 初始化失败，退出!"))
            sys.exit(1)

        # 如果上传路径不存在，则创建
        if not os.path.exists(Config.UPLOAD_FOLDER):
            print("第一次运行，创建上传文件目录{}".format(Config.UPLOAD_FOLDER))
            os.makedirs(Config.UPLOAD_FOLDER)

        if Config.CONSOLELOGLEVEL=='DEBUG':
            for key,val in Config.__dict__.items():
                if isinstance(key,str) and not key.startswith('_'):
                    print(key, '=', val)
        print('**配置文件加载完成**')
    #单例模式复写new方法
    def __new__(cls, *args, **kwargs):
        if not hasattr(Config, "_instance"):
            with Config._instance_lock:
                if not hasattr(Config, "_instance"):
                    Config._instance = object.__new__(cls)
        return Config._instance
    #初始化app对象
    def init_app(self,app):
        app.config.from_object(self)
        print('**系统初始化完成**')


if __name__ == '__main__':
    config1=Config()
    # config2=Config()
    print(config1)
    # print(config2)

